package com.colbby.datahouse.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ManagedPool<K> {

	private Map<K, K> map = new HashMap<>();
	private KeyCounter<K> counter = new KeyCounter<K>();
	private Lock lock = new ReentrantLock();
	
	/**
	 * 假如k存在，则返回池中的k， 并且记录当前的获取线程
	 * 假如k不存在，则插入，并且返回k
	 * @param k
	 * @return
	 */
	public K internAndRecord(K k) {
		lock.lock();
		try {
			if(!map.containsKey(k)) {
				map.put(k, k);
			}
			counter.add(k, 1);
			return map.get(k);
		} finally {
			lock.unlock();
		}
	}
	
	/**
	 * 尝试销毁K，假如没有任何线程在使用这个k时
	 * 若成功，则返回true
	 * 若未销毁，返回false
	 * @param k
	 */
	public K destroy(K k) {
		lock.lock();
		try {
			K k1 = map.get(k);
			counter.add(k, -1);
			if(counter.getCount(k) > 0) return k1;
			remove(k);
			return k1;
		} finally {
			lock.unlock();
		}
	}
	
	/**
	 * 直接移除K
	 * @param k
	 */
	private void remove(K k) {
		map.remove(k);
	}
	
	private static class KeyCounter<K> {
		private Map<K, Long> map = new HashMap<K, Long>();
		
		public void add(K k, long count) {
			if(map.get(k) == null) {
				map.put(k, count);
			} else {
				Long c = map.get(k);
				map.put(k, c + count);
			}
		}
		
		public long getCount(K k) {
			Long c = map.get(k);
			return c == null ? 0 : c;
		}
	} 
}
